using System.Windows;

namespace MyToDo.Common
{
    /// <summary>
    /// WPF附加属性示例类
    /// 演示如何创建支持数据绑定的附加属性
    /// </summary>
    public static class AttachedProperties
    {
        #region 示例1: 简单的附加属性 - 支持绑定

        /// <summary>
        /// IsSelected附加属性的依赖属性标识符
        /// </summary>
        public static readonly DependencyProperty IsSelectedProperty = 
            DependencyProperty.RegisterAttached(
                "IsSelected", // 属性名称
                typeof(bool), // 属性类型
                typeof(AttachedProperties), // 拥有属性的类型
                new FrameworkPropertyMetadata(
                    false, // 默认值
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | // 默认支持双向绑定
                    FrameworkPropertyMetadataOptions.Inherits, // 属性值可继承
                    OnIsSelectedChanged // 属性值变化时的回调函数
                )
            );

        /// <summary>
        /// 获取IsSelected附加属性的值
        /// </summary>
        /// <param name="element">要获取属性值的依赖对象</param>
        /// <returns>IsSelected属性的当前值</returns>
        public static bool GetIsSelected(DependencyObject element)
        {
            return (bool)element.GetValue(IsSelectedProperty);
        }

        /// <summary>
        /// 设置IsSelected附加属性的值
        /// </summary>
        /// <param name="element">要设置属性值的依赖对象</param>
        /// <param name="value">要设置的新值</param>
        public static void SetIsSelected(DependencyObject element, bool value)
        {
            element.SetValue(IsSelectedProperty, value);
        }

        /// <summary>
        /// IsSelected附加属性值变化时的回调函数
        /// </summary>
        /// <param name="d">发生属性变化的依赖对象</param>
        /// <param name="e">属性变化事件的参数</param>
        private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // 在这里可以添加属性值变化时的处理逻辑
            // 例如，根据属性值改变UI元素的外观或行为
            bool newValue = (bool)e.NewValue;
            // 可以在这里添加具体的业务逻辑
        }

        #endregion

        #region 示例2: 带有数据验证的附加属性

        /// <summary>
        /// MaxLength附加属性的依赖属性标识符
        /// </summary>
        public static readonly DependencyProperty MaxLengthProperty = 
            DependencyProperty.RegisterAttached(
                "MaxLength",
                typeof(int),
                typeof(AttachedProperties),
                new FrameworkPropertyMetadata(
                    int.MaxValue, // 默认值为最大整数值
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                    OnMaxLengthChanged
                ),
                ValidateMaxLength // 数据验证回调函数
            );

        /// <summary>
        /// 获取MaxLength附加属性的值
        /// </summary>
        public static int GetMaxLength(DependencyObject element)
        {
            return (int)element.GetValue(MaxLengthProperty);
        }

        /// <summary>
        /// 设置MaxLength附加属性的值
        /// </summary>
        public static void SetMaxLength(DependencyObject element, int value)
        {
            element.SetValue(MaxLengthProperty, value);
        }

        /// <summary>
        /// MaxLength附加属性的数据验证函数
        /// </summary>
        /// <param name="value">要验证的值</param>
        /// <returns>如果值有效则返回true，否则返回false</returns>
        private static bool ValidateMaxLength(object value)
        {
            int length = (int)value;
            return length >= 0; // 确保长度不小于0
        }

        /// <summary>
        /// MaxLength附加属性值变化时的回调函数
        /// </summary>
        private static void OnMaxLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // 检查依赖对象是否为TextBox类型
            if (d is System.Windows.Controls.TextBox textBox)
            {
                // 获取新的最大长度值
                int newMaxLength = (int)e.NewValue;
                
                // 将新的最大长度应用到TextBox的MaxLength属性
                textBox.MaxLength = newMaxLength;
                
                // 如果当前文本长度超过新的最大长度，截断文本
                if (!string.IsNullOrEmpty(textBox.Text) && textBox.Text.Length > newMaxLength)
                {
                    textBox.Text = textBox.Text.Substring(0, newMaxLength);
                    // 设置光标位置到文本末尾
                    textBox.CaretIndex = textBox.Text.Length;
                }
            }
        }

        #endregion

        #region 示例3: 支持复杂对象的附加属性

        /// <summary>
        /// TagObject附加属性的依赖属性标识符
        /// </summary>
        public static readonly DependencyProperty TagObjectProperty = 
            DependencyProperty.RegisterAttached(
                "TagObject",
                typeof(object),
                typeof(AttachedProperties),
                new FrameworkPropertyMetadata(
                    null,
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
                )
            );

        /// <summary>
        /// 获取TagObject附加属性的值
        /// </summary>
        public static object GetTagObject(DependencyObject element)
        {
            return element.GetValue(TagObjectProperty);
        }

        /// <summary>
        /// 设置TagObject附加属性的值
        /// </summary>
        public static void SetTagObject(DependencyObject element, object value)
        {
            element.SetValue(TagObjectProperty, value);
        }

        #endregion
    }
}